#include<iostream>
#include<unistd.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<cstdio>
#include<cstring>
void child_write(int writefd)
{
    //char buffer[1024]={0};
    char ch = 0;
    int cnt = 0;
    while(true)
    {
        
        //snprintf(buffer,sizeof(buffer),"i am child, pid = %d, cnt = %d\n",getpid(),cnt++);

        //测试管道大小  管道缓冲区大小一般为64K
        
        write(writefd,&ch,1);
        std::cout<<"已写入"<<++cnt<<"字节"<<std::endl;

        //break;//测试管道读端关闭
    }
}
void parent_read(int readfd)
{
    char buffer[1024]={0};
    
    while(true)
    {
        sleep(100);
        memset(buffer,0,sizeof(buffer));
        //read函数返回读取的字节数
        ssize_t n = read(readfd,buffer,sizeof(buffer)-1);
        
        if(n > 0)
        {
            //加上字符串结束符
            buffer[n] = 0;
            //输出读取到的内容
            std::cout<<"child say: "<<buffer;
        }
        else if(n == 0)
        {
            //管道被关闭
            std::cout<<"pipe has been closed"<<std::endl;
            break;
        }
        else
        {
            //读取出错
            std::cerr<<"read error"<<std::endl;
            break;
        }
        break;//测试管道写端关闭
    }
}

int main()
{
    //创建管道
    int fds[2]={0};//fds[0] read, fds[1] write
    int n = pipe(fds);

    if(n < 0)
    {
        std::cerr<<"pipe error"<<std::endl;
        return 1;
    }
    else
    {
        std::cout<<"pipe create success"<<std::endl;
        std::cout<<"read fd = "<<fds[0]<<std::endl;
        std::cout<<"write fd = "<<fds[1]<<std::endl;
    }
    //创建子进程
    pid_t rid = fork();
    if(rid == 0)//child
    {
        //3.关闭不需要的读写端
        close(fds[0]);

        child_write(fds[1]);


        close(fds[1]);
        exit(0);
    }
    else//parent
    {
        
        //3.关闭不需要的读写端
        sleep(3);
        close(fds[1]);
        parent_read(fds[0]);

        close(fds[0]);
        int status = 0;
        int ret = waitpid(rid, &status, 0);
        if(ret > 0)
        {
            printf("child exit code: %d,child signal: %d\n", (status>>8)&0xFF, (status)&0x7F);//8位表示退出码，7位表示信号值
            sleep(5);
        }
    }

    return 0;
}